package com.ywjt.pinkelephant.home.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.PermissionChecker;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.ywjt.pinkelephant.R;
import com.ywjt.pinkelephant.base.BaseActivity;
import com.ywjt.pinkelephant.util.SPUtils;
import com.ywjt.pinkelephant.widget.BackBottomDialog;
import com.ywjt.pinkelephant.widget.MyTextureview;
import com.ywjt.pinkelephant.widget.PromptBroadsetBottomDialog;
import com.ywjt.pinkelephant.widget.PromptShotsetBottomDialog;
import com.ywjt.pinkelephant.widget.RoundRelativeLayout;
import com.ywjt.pinkelephant.widget.SizeBottomDialog;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ActivityPromptShot extends BaseActivity implements View.OnClickListener, View.OnTouchListener  {
    private MyTextureview mTextureView;
    private LinearLayout llChangeCamera;
    private RoundRelativeLayout llContainer;
    private ImageView ivStartPlay,ivModeChange,ivHidden,ivShow;
    private LinearLayout llSize;
    private ImageView ivPopuSet,ivAi;
    private TextView tvText;
    private ScrollView scrollView;

    private Boolean isFullScreen=false;
    private Boolean isPlay=false;
    private final Handler mHandler = new Handler();

    /**当前触摸模式：无触摸；单指触摸；双指触摸；*/
    private int currentTouchMode = TOUCH_NONE ;
    private static final int TOUCH_NONE = 0x00;
    private static final int TOUCH_ONE = 0x20;
    private int lastX;
    private int lastY;
    private int newX;
    private int newY;
    //刚触摸时的view坐标（用来获取按下时view的大小）
    private int oriLeft=0;
    private int oriRight=90;
    private int oriTop=160;
    private int oriBottom=0;
    private float baseValue;
    /*** 是否取消：触摸移动*/
    private boolean isCancleTouchDrag = false;
    private float lastScale = 1;
    /*** 是否开启：双指触摸缩放*/
    private boolean touchTwoZoomEnable = true;
    private int maxWidth;
    private int maxHeight;
    private Boolean isAi=false;

    /***********本地广播*************/
    public static LocalBroadcastManager localBroadcastManager;
    private MyBroadcastReceiver myBroadcastReceiver;
    private IntentFilter filter;
    public static String LOCAL_BROADCAST = "com.ywjt.pinkelephant.home.activity.ActivityPromptShot";

    public void registerMessageReceiver() {
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        myBroadcastReceiver = new MyBroadcastReceiver();
        filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(LOCAL_BROADCAST);
        localBroadcastManager.registerReceiver(myBroadcastReceiver, filter);
    }

    public class MyBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                if (LOCAL_BROADCAST.equals(intent.getAction())) {
                    switch (intent.getIntExtra("action", 1)) {
                        case 1:
                            //背景透明度
                            float t=Float.parseFloat(intent.getStringExtra("value"));
                            llContainer.setAlpha((100-t)/100);
                            SPUtils.setSharedFloatData(ActivityPromptShot.this,"VideoTextTransparent",t);
                            break;
                        case 2:
                            if (intent.getStringExtra("value").equals("0")){
                                //字体颜色
                                tvText.setTextColor(intent.getIntExtra("color",0));
                                SPUtils.setSharedIntData(ActivityPromptShot.this,"VideoTextColor",intent.getIntExtra("color",0));
                            }else {
                                //背景颜色
                                llContainer.setBackgroundColor(intent.getIntExtra("color",0));
                                SPUtils.setSharedIntData(ActivityPromptShot.this,"VideoBgColor",intent.getIntExtra("color",0));
                            }
                            break;
                        case 3:
                            float size=Float.parseFloat(intent.getStringExtra("value"));
                            tvText.setTextSize(size);
                            SPUtils.setSharedFloatData(ActivityPromptShot.this,"BoardTextSize",size);
                            break;
                        case 5:
                            SPUtils.setSharedIntData(ActivityPromptShot.this,"VideoTextSpeed",Integer.parseInt(intent.getStringExtra("value")));
                            break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void actionStart(Context context ) {
        Intent intent = new Intent(context, ActivityPromptShot.class);
        context.startActivity(intent);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.ivAi:
                //ai
                if (!isAi){
                    SPUtils.setSharedBooleanData(ActivityPromptShot.this,"VideoIsAi",true);
                    ivAi.setImageResource(R.mipmap.icon_ai_orange);
                }else {
                    ivAi.setImageResource(R.mipmap.icon_ai);
                    SPUtils.setSharedBooleanData(ActivityPromptShot.this,"VideoIsAi",false);
                }
                isAi=!isAi;
                break;
            case R.id.llChangeCamera:
                switchCameraFacing();
                break;
            case R.id.ivStartPlay:
                //开始提词拍摄
                if (!isPlay){
                    if (SPUtils.getSharedBooleanData(ActivityPromptShot.this,"VideoIsAi")){
                        //是ai提词
                        mHandler.post(ScrollRunnable);
                    }
                    ivStartPlay.setImageResource(R.mipmap.icon_video_play);
                }else {
                    ivStartPlay.setImageResource(R.mipmap.icon_shot);
                    if (SPUtils.getSharedBooleanData(ActivityPromptShot.this,"VideoIsAi")){
                        mHandler.removeCallbacks(ScrollRunnable);
                    }
                }
                isPlay=!isPlay;
                break;
            case R.id.llSize:
                //尺寸
                SizeBottomDialog sizeBottomDialog=new SizeBottomDialog(ActivityPromptShot.this);
                sizeBottomDialog.setClicklistener(new SizeBottomDialog.ClickListenerInterface() {
                    @Override
                    public void callback(int mode) {
                        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mTextureView.getLayoutParams();

                        switch (mode){
                            case 1:
                                //全面屏
                                params.height = maxHeight;
                                params.width=maxWidth;
                                mTextureView.setLayoutParams(params);
                                SPUtils.setSharedStringData(ActivityPromptShot.this,"TextureViewSize","0");
                                sizeBottomDialog.dismiss();
                                break;
                            case 2:
                                //9：16
                                params.height = mTextureView.getWidth()*16/9;
                                params.width=mTextureView.getWidth();
                                mTextureView.setLayoutParams(params);
                                SPUtils.setSharedStringData(ActivityPromptShot.this,"TextureViewSize","9");

                                sizeBottomDialog.dismiss();

                                break;
                            case 3: //3：4
                                params.height = mTextureView.getWidth()*4/3;
                                params.width=mTextureView.getWidth();
                                mTextureView.setLayoutParams(params);
                                SPUtils.setSharedStringData(ActivityPromptShot.this,"TextureViewSize","3");
                                sizeBottomDialog.dismiss();
                                break;
                            case 4:
                                //1：1
                                params.height = mTextureView.getWidth();
                                params.width=mTextureView.getWidth();
                                mTextureView.setLayoutParams(params);
                                SPUtils.setSharedStringData(ActivityPromptShot.this,"TextureViewSize","1");
                                sizeBottomDialog.dismiss();
                                break;
                        }
                    }
                });
                sizeBottomDialog.show(getSupportFragmentManager());
                break;
            case R.id.ivModeChange:
                //横竖屏切换
                if (!isFullScreen){
                    ivStartPlay.setRotation(90);
                    llSize.setRotation(90);
                    llChangeCamera.setRotation(90);
                    llContainer.setRotation(90);
                }else {
                    ivStartPlay.setRotation(0);
                    llSize.setRotation(0);
                    llChangeCamera.setRotation(0);
                    llContainer.setRotation(0);
                }
                isFullScreen=!isFullScreen;
                break;
            case R.id.ivPopuSet:
                //悬浮窗设置
                PromptShotsetBottomDialog bottomDialog=new PromptShotsetBottomDialog(ActivityPromptShot.this);
                bottomDialog.show(getSupportFragmentManager());
                break;
            case R.id.ivHidden:
                llContainer.setVisibility(View.GONE);
                ivShow.setVisibility(View.VISIBLE);
                break;
            case R.id.ivShow:
                llContainer.setVisibility(View.VISIBLE);
                ivShow.setVisibility(View.GONE);
                break;
        }
    }

    @Override
    protected void init(Bundle savedInstanceState) {
        setAndroidNativeLightStatusBar(false);
    }

    @Override
    protected int setLayoutResourceID() {
        return R.layout.activity_prompt_shot;
    }

    @Override
    protected void initView() {
        registerMessageReceiver();
        Display dp = getWindowManager().getDefaultDisplay();
        maxWidth = dp.getWidth();
        maxHeight = dp.getHeight();
        mTextureView=findViewById(R.id.camera2);
        llSize=findViewById(R.id.llSize);
        ivShow=findViewById(R.id.ivShow);
        ivPopuSet=findViewById(R.id.ivPopuSet);
        scrollView=findViewById(R.id.scrollView);
        llChangeCamera=findViewById(R.id.llChangeCamera);
        llContainer=findViewById(R.id.llContainer);
        llContainer.setRadius(17);
        ivStartPlay=findViewById(R.id.ivStartPlay);
        ivModeChange=findViewById(R.id.ivModeChange);
        ivHidden=findViewById(R.id.ivHidden);
        ivAi=findViewById(R.id.ivAi);
        tvText=findViewById(R.id.tvText);

        ivAi.setOnClickListener(this::onClick);
        llContainer.setOnTouchListener(this);
        ivHidden.setOnClickListener(this::onClick);
        ivPopuSet.setOnClickListener(this::onClick);
        ivShow.setOnClickListener(this::onClick);
        ivModeChange.setOnClickListener(this::onClick);
        ivStartPlay.setOnClickListener(this::onClick);
        llSize.setOnClickListener(this::onClick);
        llChangeCamera.setOnClickListener(this::onClick);
        mTextureView.setSurfaceTextureListener(mTextureListener);


    }

    private TextureView.SurfaceTextureListener mTextureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            //当SurefaceTexture可用的时候，设置相机参数并打开相机
            setupCamera(width, height);
            openCamera();
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            setupCamera(width, height);
            openCamera();
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { return false; }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) { }
    };


    private void setupCamera(int width, int height) {
        //获取摄像头的管理者CameraManager
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            //遍历所有摄像头
            for (String cameraId : manager.getCameraIdList()) {
                CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
                Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
                //此处默认打开后置摄像头
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK)
                    continue;
                //获取StreamConfigurationMap，它是管理摄像头支持的所有输出格式和尺寸
                StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                assert map != null;
                //根据TextureView的尺寸设置预览尺寸
                List<Size> data=new ArrayList<>();
                for(int i=0;i<map.getOutputSizes(SurfaceTexture.class).length;i++){
                    data.add(map.getOutputSizes(SurfaceTexture.class)[i]);
                }
                mPreviewSize = getOptimalSize(data, width, height);
                mCameraId = cameraId;
                break;
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private void openCamera() {
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            manager.openCamera(mCameraId, mStateCallback, mCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice camera) {
            mCameraDevice = camera;
            startPreview();
        }

        @Override
        public void onDisconnected(CameraDevice camera) {
            camera.close();
            mCameraDevice = null;
        }

        @Override
        public void onError(CameraDevice camera, int error) {
            camera.close();
            mCameraDevice = null;
        }
    };

    private void startPreview() {
        SurfaceTexture mSurfaceTexture = mTextureView.getSurfaceTexture();
        mSurfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        Surface previewSurface = new Surface(mSurfaceTexture);
        try {
            mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mCaptureRequestBuilder.addTarget(previewSurface);
            mCameraDevice.createCaptureSession(Arrays.asList(previewSurface), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(CameraCaptureSession session) {
                    if(mCameraDevice==null){
                        return;
                    }

                    try {
                        mCaptureRequest = mCaptureRequestBuilder.build();
                        mCameraCaptureSession = session;
                        mCameraCaptureSession.setRepeatingRequest(mCaptureRequest, null, mCameraHandler);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(CameraCaptureSession session) { }
            }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }


    protected Size getOptimalSize(List<Size> preSizeList,int surfaceWidth, int surfaceHeight) {
        int ReqTmpWidth;
        int ReqTmpHeight;
        // 当屏幕为垂直的时候需要把宽高值进行调换，保证宽大于高
        ReqTmpWidth = surfaceHeight;
        ReqTmpHeight = surfaceWidth;
        for (Size size : preSizeList) {
            if ((size.getWidth() == ReqTmpWidth) && (size.getHeight() == ReqTmpHeight)) {
                return size;
            }
        }
        // 得到与传入的宽高比最接近的size
        float reqRatio = ((float) ReqTmpWidth) / ReqTmpHeight;
        float curRatio, deltaRatio;
        float deltaRatioMin = Float.MAX_VALUE;
        Size retSize = null;
        for (Size size : preSizeList) {
            curRatio = ((float) size.getWidth()) / size.getHeight();
            deltaRatio = Math.abs(reqRatio - curRatio);
            if (deltaRatio < deltaRatioMin) {
                deltaRatioMin = deltaRatio;
                retSize = size;
            }
        }
        return retSize;
    }

    private String mCameraId="1";
    private Size mPreviewSize;
    private Handler mCameraHandler;
    private CameraDevice mCameraDevice;
    private CaptureRequest.Builder mCaptureRequestBuilder;
    private CaptureRequest mCaptureRequest;
    private CameraCaptureSession mCameraCaptureSession;

    @Override
    protected void initData() {
        if (SPUtils.getSharedBooleanData(ActivityPromptShot.this,"VideoIsAi")){
            ivAi.setImageResource(R.mipmap.icon_ai_orange);
        }else {
            ivAi.setImageResource(R.mipmap.icon_ai);
        }

        if (SPUtils.getSharedIntData(ActivityPromptShot.this,"VideoTextColor")!=0){
            tvText.setTextColor(SPUtils.getSharedIntData(ActivityPromptShot.this,"VideoTextColor"));
        }

        if (SPUtils.getSharedIntData(ActivityPromptShot.this,"VideoBgColor")!=0){
            llContainer.setBackgroundColor(SPUtils.getSharedIntData(ActivityPromptShot.this,"VideoBgColor"));
        }

        if (SPUtils.getSharedIntData(ActivityPromptShot.this,"VideoTextSize")!=0){
            tvText.setTextSize(SPUtils.getSharedIntData(ActivityPromptShot.this,"VideoTextSize"));
        }

        if (SPUtils.getSharedFloatData(ActivityPromptShot.this,"VideoTextTransparent")!=0){
            llContainer.setAlpha((100-SPUtils.getSharedFloatData(ActivityPromptShot.this,"VideoTextTransparent"))/100);
        }
    }

    /**
     * 获取要使用的标题栏样式(此函数由子类重写)
     * @return
     */
    @Override
    protected int getTitleBarType() {
        return TITLEBAR_NULL;
    }

    // 移动
    private void touchDrag(View v, MotionEvent event) {
        int dx = (int) event.getRawX() - lastX;
        int dy = (int) event.getRawY() - lastY;
            int left = v.getLeft() +dx;
            int top = v.getTop() + dy;
            int right = v.getRight() + dx;
            int bottom = v.getBottom() + dy;
            if (maxWidth !=0 && maxHeight!=0) {

                //防止移出屏幕
                if(left < 0){
                    left = 0;
                    right = left + v.getWidth();
                }
                if(right > maxWidth){
                    right = maxWidth;
                    left = right - v.getWidth();
                }
                if(top < 0){
                    top = 0;
                    bottom = top + v.getHeight();
                }
                if(bottom > maxHeight){
                    bottom = maxHeight;
                    top = bottom - v.getHeight();
                }
            }
            v.layout(left, top, right, bottom);
        lastX = (int) event.getRawX();
        lastY = (int) event.getRawY();
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction()& MotionEvent.ACTION_MASK;
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                //当前触摸位置的坐标
                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
                //得到相对父控件的坐标
                oriLeft = v.getLeft();
                oriRight = v.getRight();
                oriTop = v.getTop();
                oriBottom = v.getBottom();
                currentTouchMode = TOUCH_ONE;
                baseValue = 0;
                lastScale = 1;
                break;
            /**
             * layout(l,t,r,b)
             * l  Left position, relative to parent
             t  Top position, relative to parent
             r  Right position, relative to parent
             b  Bottom position, relative to parent
             * */
            case MotionEvent.ACTION_MOVE:
                 if (currentTouchMode == TOUCH_ONE) {//1个手指
                     touchDrag(llContainer, event);
                 }
                break;
            default:
                currentTouchMode = TOUCH_NONE;
                break;
        }
        return true;
    }

    /**
     * 当前相机（前置、后置）
     */
    private int mCurrentCameraFacing = CameraCharacteristics.LENS_FACING_BACK;

    public void switchCameraFacing() {
        mCurrentCameraFacing = mCurrentCameraFacing == CameraCharacteristics.LENS_FACING_BACK ?
                CameraCharacteristics.LENS_FACING_FRONT : CameraCharacteristics.LENS_FACING_BACK;
        mCameraId = String.valueOf(mCurrentCameraFacing);
        if (mCameraId == null) {
            mCameraId = String.valueOf(1);
        }
        closeCamera();
        openCamera();
    }

    /**
     * 关闭相机
     */
    private void closeCamera() {
        if (null != mCameraCaptureSession) {
            mCameraCaptureSession.close();
            mCameraCaptureSession = null;
        }
        if (null != mCameraDevice) {
            mCameraDevice.close();
            mCameraDevice = null;
        }
    }

    /**
     * 滚屏的线程
     */
    private Runnable ScrollRunnable = new Runnable() {
        @SuppressLint("NewApi")
        @Override
        public void run() {
            int off = tvText.getMeasuredHeight() - scrollView.getHeight();// 判断高度
            if (off > 0) {
                scrollView.scrollBy(0,(SPUtils.getSharedIntData(ActivityPromptShot.this,"VideoTextSpeed")==0?
                        20/10:SPUtils.getSharedIntData(ActivityPromptShot.this,"VideoTextSpeed")/10));
                if (scrollView.getScaleY() == off) {
                    Thread.currentThread().interrupt();
                } else {
                    mHandler.postDelayed(this, 100);
                }
            }
        }
    };
}